
use std::collections::HashMap;

use std::sync::mpsc::{SyncSender, Receiver};
use std::io;
use std::io::{Error, ErrorKind};

use ws;

use serde::Serialize;
use serde_json;

use super::message;
use super::channel::Channel;


///连接map的初始size，初始size不用太大，因为应该没什么用户量。
const MAP_INIT_SIZE: usize = 16;

///管理网络连接
pub struct Connections{
    channel_map: HashMap<u32, Channel>,
    sender: SyncSender<message::Message>,
    receiver: Receiver<message::Message>
}

impl Connections{
    pub fn new(sender: SyncSender<message::Message>, receiver: Receiver<message::Message>) -> Connections{
        Connections{
            channel_map: HashMap::<u32, Channel>::with_capacity(MAP_INIT_SIZE),
            sender,
            receiver
        }
    }

    ///有玩家接入，将玩家连接管理起来。
    pub fn put_channel(&mut self, channel: Channel){
        let _ = self.channel_map.insert(channel.id(), channel);
    }

    ///循环处理消息。包括两类消息：主线程发来的消息，和从用户连接读取的消息。
    pub fn loop_message(&mut self){
        loop{
            let ret = self.receiver.try_recv();
            match ret {
                Ok(message) => self.receiver_handle(message),
                Err(e) => break
            }
        }
        let mut failures = Vec::<u32>::new();
        for socket in self.channel_map.values_mut(){
            let id = socket.id();
            let ret = socket.read_message();
            match ret {
                Ok(message) => {
                    net_handle(id, message, &self.sender);
                },
                Err(e) => {
                    error!("Receive message from connection {} error. {}", id, e);
                    match e {
                        ws::Error::ConnectionClosed(_) => {
                            //通知控制线程，有连接丢失
                            let notify = json!({"code": "lose_connection", "body": id});
                            self.sender.send(message::Message::new(id, notify.to_string()));
                            failures.push(id);
                        }
                        _ => ()
                    }
                }
            }
        }
        for conn in &failures{
            self.channel_map.remove(conn);
            info!("Removed one connection from conn map, id: {}", conn);
        }
    }

    ///主线程消息处理
    pub fn receiver_handle(&mut self, message: message::Message){
        let id = message.channel_id();
        let msg = ws::Message::from(message.data());
        let channel = self.channel_map.get_mut(&id);
        match channel {
            Some(c) => {c.send_message(msg);},
            None => error!("Can not find user channel with channel_id: {}", id),
        };
    }
}

///用户网络消息处理
pub fn net_handle(id: u32, message: ws::Message, sender: &SyncSender<message::Message>){
    match message {
        ws::Message::Text(json) => handle_message(id, json, sender),
        ws::Message::Binary(bytes) => {
            unsafe {
                let json = String::from_utf8_unchecked(bytes);
                handle_message(id, json, sender);
            }
        }
        ws::Message::Ping(_) |
        ws::Message::Pong(_) => {}
    }
}


///收到玩家消息，转发给主线程处理
fn handle_message(id: u32, json: String, sender: &SyncSender<message::Message>){
    let message = message::Message::new(id, json);
    sender.send(message);
}